package extend.part6;

import java.util.ArrayList;
import java.util.List;

public class WildcardDemo {

    // 1. 无界通配符<?>：可接受任意类型的泛型列表，只能读取（不能写入非null值）
    public static void printAnyList(List<?> list) {
        System.out.println("列表内容：");
        for (Object obj : list) { // 只能用Object接收（因为类型未知）
            System.out.println(obj);
        }
    }

    // 2. 上界通配符<? extends Person>：只接受Person及其子类的列表（生产者：适合读取）
    public static void printPersons(List<? extends Person> persons) {
        System.out.println("人员列表：");
        for (Person p : persons) { // 可安全转型为Person（因为元素都是Person的子类）
            System.out.println(p);
        }
        // 注意：上界通配符的列表不能写入元素（除null）
        // persons.add(new Person("张三")); // 编译错误：无法确定列表实际类型（可能是Student列表，加Person不安全）
    }

    // 3. 下界通配符<? super Student>：只接受Student及其父类的列表（消费者：适合写入）
    public static void addStudents(List<? super Student> list) {
        // 可以写入Student及其子类（因为父类列表可存放子类对象）
        list.add(new Student("小明", 1001));
        list.add(new Student("小红", 1002));
        // 注意：下界通配符的列表读取时只能用Object接收
        for (Object obj : list) { // 无法确定具体类型（可能是Person/Object列表）
            System.out.println("读取元素：" + obj);
        }
    }

    public static void main(String[] args) {
        // 准备测试数据
        List<Person> personList = new ArrayList<>();
        personList.add(new Person("路人甲"));
        personList.add(new Teacher("李老师", 2001));

        List<Student> studentList = new ArrayList<>();
        studentList.add(new Student("小刚", 1003));

        List<Teacher> teacherList = new ArrayList<>();
        teacherList.add(new Teacher("王老师", 2002));

        List<String> stringList = new ArrayList<>();
        stringList.add("测试字符串");


        // 测试无界通配符<?>：可接受任何类型的列表
        System.out.println("=== 无界通配符测试 ===");
        printAnyList(personList);   // 合法：Person列表
        printAnyList(studentList);  // 合法：Student列表
        printAnyList(stringList);   // 合法：String列表（无界不限制类型）


        // 测试上界通配符<? extends Person>：只接受Person及其子类
        System.out.println("\n=== 上界通配符测试 ===");
        printPersons(personList);   // 合法：Person是自身的子类
        printPersons(studentList);  // 合法：Student是Person的子类
        printPersons(teacherList);  // 合法：Teacher是Person的子类
        // printPersons(stringList); // 编译错误：String不是Person的子类


        // 测试下界通配符<? super Student>：只接受Student及其父类
        System.out.println("\n=== 下界通配符测试 ===");
        List<Person> personList2 = new ArrayList<>();
        addStudents(personList2);   // 合法：Person是Student的父类

        List<Object> objectList = new ArrayList<>();
        addStudents(objectList);    // 合法：Object是Student的父类（顶级父类）

        List<Student> studentList2 = new ArrayList<>();
        addStudents(studentList2);  // 合法：Student是自身的父类（super包含自身）

         List<Teacher> teacherList2 = new ArrayList<>();
         //addStudents(teacherList2); // 编译错误：Teacher不是Student的父类
    }
}